﻿using Microsoft.Xna.Framework;
using FarseerPhysics.Dynamics;
using lumo.display.object2D;
using lumo.display;
using System;
using Microsoft.Xna.Framework.Graphics;
using lumo;
using game.character.battle;

namespace game.character
{

    /// <summary>
    /// Game character class.
    /// </summary>
    public abstract class GameCharacter : IDisposable, ICroppable, IUpdatable
    {
        //-- Character Var
        /// <summary>The Lumo Component</summary>
        protected LumoComponent _LumoComponent;
        /// <summary>The Map</summary>
        protected GameMap _GameMap;
        /// <summary>Physics body</summary>
        public Body Body { get; protected set; }
        /// <summary>Position of character on the map.</summary>
        public Vector2 Position { get { return Vector2.Multiply(Body.Position, Global.PhysicsScale); } set { Body.Position = Vector2.Divide(value, Global.PhysicsScale); } }
        /// <summary>Texture</summary>
        public Texture2D Texture { get; protected set; }
        /// <summary>Battler</summary>
        public GameBattler Battler;

        //-- Screen Attributes
        /// <summary>Position of character on screen.</summary>
        public Vector2 ScreenPosition { get { return (this.Position - Global.Camera.ScreenPosition); } }
        /// <summary>Origin of the sprite character.</summary>
        public Vector2 ScreenOrigin { get; protected set; }
        /// <summary>Angle of character on screen.</summary>
        public float ScreenRadians { get { return Body.Rotation; } }
        /// <summary>High priority character</summary>
        public bool ScreenHighPriority = false;
        /// <summary>Cast shadow</summary>
        public bool ScreenCastShadow = false;
        /// <summary>Cast shadow</summary>
        public bool ScreenMirrorX = false;
        /// <summary>Cast shadow</summary>
        public bool ScreenMirrorY = false;

        /// <summary>
        /// Constructor.
        /// </summary>
        public GameCharacter(LumoComponent component, GameMap map)
        {
            this._LumoComponent = component;
            this._GameMap = map;
        }

        /// <summary>
        /// Setup the character.
        /// </summary>
        public virtual void Setup()
        {
            CreateBody();
            if (Body == null)
                throw new Exception("No body was created");
            Body.UserData = this;
        }

        /// <summary>
        /// Abstract method to create the body.
        /// </summary>
        protected abstract void CreateBody();

        /// <summary>
        /// Called when hit.
        /// </summary>
        public virtual void OnHit()
        {
        }

        /// <summary>
        /// Update the character.
        /// </summary>
        /// <param name="component">Update using lumo</param>
        public virtual void Update(LumoComponent component)
        {
        }

        //-- IDposable interface implementation
        /// <summary>
        /// Dispose the character.
        /// </summary>
        public virtual void Dispose()
        {
            // Dispose the body.
            if (Body != null)
                Global.Map.World.RemoveBody(Body);
        }

        //-- ICroppable Interface
        /// <summary>Texture</summary>
        public Vector2 OriginalSize { get { return (Texture == null ? Vector2.Zero : new Vector2(Texture.Width, Texture.Height)); } }
        /// <summary>Texture</summary>
        public Rectangle? SourceRectangle { get; set; }
    }

}